package com.example.aspect.common;

import com.example.annotation.common.OperateLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author LiYuhang
 * @version 0.1
 * @application
 * @Copyright 上海危网信息科技有限公司版权所有
 * @company wwsoft
 * @Date 2019/11/20 16:30
 */
@Aspect
@Component
@Slf4j
public class OperateLogAspect {
    private static ThreadLocal<ProceedingJoinPoint> threadLocal = new ThreadLocal<>();

    @Pointcut("@within(com.example.annotation.common.OperateLog) || @annotation(com.example.annotation.common.OperateLog)")
    @Order(1)
    public void operateLog( ){}

    @Before("operateLog()")
    public void doBefore(JoinPoint point){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        OperateLog syslog = method.getAnnotation(OperateLog.class);
        log.info("\n------------------{}{}",syslog.description(),"-----------------------");
        log.info("\n请求URL:{}",request.getRequestURL());
        log.info("\n请求参数:{}", Arrays.toString(point.getArgs()));
    }
    @Around("operateLog()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        threadLocal.set(point);
        long startTime = System.currentTimeMillis();
        ProceedingJoinPoint joinPoint = threadLocal.get();
        Object proceed = joinPoint.proceed();
        log.info("\n执行耗时毫秒:{}", (System.currentTimeMillis()-startTime));
        return proceed;
    }
}
